package org.locker.netty;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.locker.common.core.exception.ServiceException;
import org.locker.common.core.utils.StringUtils;
import org.locker.common.oss.core.OssClient;
import org.locker.common.oss.entity.UploadResult;
import org.locker.common.oss.factory.OssFactory;
import org.locker.domain.*;
import org.locker.domain.bo.DeviceOperateLogBo;
import org.locker.domain.enums.DeviceGridStatusEnum;
import org.locker.domain.enums.DeviceStatusEnum;
import org.locker.domain.enums.OrderPayWayEnum;
import org.locker.domain.enums.OrderStatusEnum;
import org.locker.netty.dto.MessageEnum;
import org.locker.netty.dto.MessageObject;
import org.locker.netty.dto.command.*;
import org.locker.netty.dto.reply.GetSimInfoReply;
import org.locker.netty.dto.reply.QueryApkLastVersionD2sReply;
import org.locker.netty.dto.reply.SynchronousGridListReply;
import org.locker.netty.dto.resp.BindResp;
import org.locker.netty.dto.resp.VerifyCardResp;
import org.locker.service.*;
import org.locker.system.domain.vo.SysOssVo;
import org.locker.system.service.ISysConfigService;
import org.locker.system.service.ISysOssService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static org.locker.common.oss.constant.OssConstant.SYS_FREE_MINUTES_KEY;

/**
 * @author: winnie
 * @create: 2023-10-12
 * @Description:
 */
@Slf4j
@Service
@Transactional
@RequiredArgsConstructor
public class MachineService {

    private final IBluetoothVersionService bluetoothVersionService;

    private final IDeviceVersionService deviceVersionService;

    private final IDeviceService deviceService;

    private final ISysOssService sysOssService;

    private final IUserService userService;


    private final IDeviceGridService deviceGridService;

    private final IPositionService positionService;

    private final ISysConfigService sysConfigService;


    private final ICommonService commonService;

    private final IOrderService orderService;

    private final IDeviceOperateLogService deviceOperateLogService;

    private final IDeviceUploadLogService deviceUploadLogService;

    private final MessageService messageService;

    private final ScheduledExecutorService scheduledExecutorService;
    // yml中指定netty端口号
    @Value("${netty.port}")
    private int nettyPort;

    // yml中指定netty端口号
    @Value("${netty.host}")
    private String nettyHost;


    /**
     * 设置设备信息
     *
     * @param bindResp
     * @param device
     * @return
     */
    public static BindResp setDeviceInfo(BindResp bindResp, Device device) {
        bindResp.setPositionId(device.getPositionId());
        bindResp.setDeviceId(device.getDeviceId());
        bindResp.setDeviceNo(device.getDeviceNo());
        bindResp.setDeviceQrCode(device.getDeviceQrCode());
        if(device.getIsShowMp()!=null&&device.getIsShowMp()==1){
            bindResp.setDeviceQrCode(device.getDeviceMpQrCode());
        }
        bindResp.setIsShowMp(device.getIsShowMp());
        bindResp.setDeviceMpQrCode(device.getDeviceMpQrCode());
        bindResp.setDevicePwd(device.getDevicePwd());
        bindResp.setName(device.getName());
        bindResp.setDescribe(device.getDescribe());
        bindResp.setDeviceLocation(device.getDeviceLocation());
        bindResp.setStatus(device.getStatus());
        if (device.getConnectTime() != null) {
            bindResp.setConnectTime(device.getConnectTime().getTime());
        }
        bindResp.setAdminUser(device.getAdminUser());
        bindResp.setAdminPwd(device.getAdminPwd());
        bindResp.setGardNum(device.getGardNum());
        bindResp.setDeviceImei(device.getDeviceImei());
        bindResp.setDeviceCardNo(device.getDeviceCardNo());
        bindResp.setDeviceIccid(device.getDeviceIccid());
        bindResp.setDeviceType(device.getDeviceType());
        //处理获取配置，从配置信息获取
        bindResp.setFeeConfig(device.getFeeConfig());
        bindResp.setFeeType(device.getFeeType());
        bindResp.setDepositAmount(device.getDepositAmount());
        return bindResp;
    }


    /**
     * 设置设备格子
     *
     * @return
     */
    public static void setDeviceGrids(BindResp bindResp, List<DeviceGrid> deviceGrids) {
        List<BindResp.DeviceGridDto> deviceGridDtos = new ArrayList<>();
        for (DeviceGrid deviceGrid : deviceGrids) {
            BindResp.DeviceGridDto deviceGridDto = getDeviceGridDto(deviceGrid);
            deviceGridDtos.add(deviceGridDto);
        }
        bindResp.setDeviceGrids(deviceGridDtos);
    }

    /**
     * 场地信息
     *
     * @return
     */
    public static void setPositionInfo(BindResp bindResp, Position position) {
        BindResp.PositionDto positionDto = getPositionDto(position, null);
        //修改从设备信息获取
        positionDto.setDepositAmount(bindResp.getDepositAmount());
        positionDto.setPositionConfig(bindResp.getFeeConfig());
        positionDto.setPositionType(bindResp.getFeeType());
        bindResp.setPositionInfo(positionDto);
    }

    /**
     * 场地信息
     *
     * @return
     */
    public static void setCommonInfo(BindResp bindResp, Common common) {
        BindResp.CommonDto commonDto = getCommonDto(common);
        bindResp.setCommonInfo(commonDto);
    }


    /**
     * 设置格子状态
     *
     * @param deviceGrid
     * @return
     */
    public static DeviceSingleLockStatusReply setGridLockReply(DeviceGrid deviceGrid) {
        DeviceSingleLockStatusReply deviceSingleLockStatusReply = new DeviceSingleLockStatusReply();
        deviceSingleLockStatusReply.setDeviceNo(deviceGrid.getDeviceNo());
        deviceSingleLockStatusReply.setDeviceGridId(deviceGrid.getDeviceGridId());
        deviceSingleLockStatusReply.setSerialNo(deviceGrid.getSerialNo());
        deviceSingleLockStatusReply.setSerialIndex(deviceGrid.getSerialIndex());
        deviceSingleLockStatusReply.setMacNo(deviceGrid.getMacNo());
        deviceSingleLockStatusReply.setGridType(deviceGrid.getGridType());
        deviceSingleLockStatusReply.setStatus(deviceGrid.getStatus());
        return deviceSingleLockStatusReply;
    }

    public static PushOrder getPushOrder(Order order) {
        PushOrder pushOrder = new PushOrder();
        pushOrder.setUserId(order.getUserId());
        pushOrder.setPhone(order.getPhone());
        pushOrder.setDeviceNo(order.getDeviceNo());
        pushOrder.setDeviceGridId(order.getDeviceGridId());
        pushOrder.setOpenPwd(order.getOpenPwd());
        pushOrder.setOrderNo(order.getOrderNo());
        if (order.getStartTime() != null) {
            pushOrder.setStartTime(order.getStartTime().getTime());
        }
        if (order.getEndTime() != null) {
            pushOrder.setEndTime(order.getEndTime().getTime());
        }
        pushOrder.setOrderStatus(order.getOrderStatus());
        pushOrder.setIdNo(order.getIdNo());
        pushOrder.setIsOffline(order.getIsOffline());
        pushOrder.setOrderType(order.getOrderType());
        pushOrder.setPayWay(order.getPayWay());
        return pushOrder;
    }


    @NotNull
    private static BindResp.DeviceGridDto getDeviceGridDto(DeviceGrid deviceGrid) {
        BindResp.DeviceGridDto deviceGridDto = new BindResp.DeviceGridDto();
        deviceGridDto.setDeviceGridId(deviceGrid.getDeviceGridId());
        deviceGridDto.setName(deviceGrid.getName());
        deviceGridDto.setNumber(deviceGrid.getNumber());
        deviceGridDto.setSerialNo(deviceGrid.getSerialNo());
        deviceGridDto.setSerialIndex(deviceGrid.getSerialIndex());
        deviceGridDto.setMacNo(deviceGrid.getMacNo());
        deviceGridDto.setGridType(deviceGrid.getGridType());
        deviceGridDto.setStatus(deviceGrid.getStatus());
        deviceGridDto.setRemark(deviceGrid.getRemark());
        deviceGridDto.setOrderNo(deviceGrid.getOrderNo());
        deviceGridDto.setSpecCode(deviceGrid.getSpecCode());
        deviceGridDto.setSpecPrice(deviceGrid.getSpecPrice());
        return deviceGridDto;
    }

    @NotNull
    public static ControlOpen getControlOpen(DeviceGrid deviceGrid, Order order) {
        ControlOpen controlOpen = new ControlOpen();
        if (order != null) {
            String orderNo = order.getOrderNo();
            controlOpen.setOrderNo(orderNo);
        }
        controlOpen.setDeviceNo(deviceGrid.getDeviceNo());
        controlOpen.setDeviceGridId(deviceGrid.getDeviceGridId());
        controlOpen.setName(deviceGrid.getName());
        controlOpen.setNumber(deviceGrid.getNumber());
        controlOpen.setMacNo(deviceGrid.getMacNo());
        controlOpen.setSerialNo(deviceGrid.getSerialNo());
        controlOpen.setSerialIndex(deviceGrid.getSerialIndex());
        return controlOpen;
    }

    @NotNull
    private static BindResp.CommonDto getCommonDto(Common common) {
        BindResp.CommonDto commonDto = new BindResp.CommonDto();
        commonDto.setBrandName(common.getBrandName());
        commonDto.setEnglishName(common.getEnglishName());
        commonDto.setServicePhone(common.getServicePhone());
        commonDto.setServiceTime(common.getServiceTime());
        return commonDto;
    }

    @NotNull
    private static BindResp.PositionDto getPositionDto(Position position, Device device) {
        BindResp.PositionDto positionDto = new BindResp.PositionDto();
        positionDto.setPositionId(position.getPositionId());
//        positionDto.setUsername(position.getUsername());
//        positionDto.setPhone(position.getPhone());
        positionDto.setWorkTime(position.getWorkTime());
        positionDto.setName(position.getName());
        positionDto.setDescribe(position.getDescribe());
        positionDto.setLocation(position.getLocation());
        positionDto.setLongitude(position.getLongitude());
        positionDto.setLatitude(position.getLatitude());
        positionDto.setQrCode(position.getQrCode());
        positionDto.setStatus(position.getStatus());
        if (device != null) {
            //处理场地新根据设备走
            positionDto.setDepositAmount(device.getDepositAmount());
            positionDto.setPositionConfig(device.getFeeConfig());
            positionDto.setPositionType(device.getFeeType());

        }

        positionDto.setRemark(position.getRemark());
        return positionDto;
    }

    public static DeviceSingleLockStatus getDeviceSingleLockStatus(DeviceGrid deviceGrid) {
        DeviceSingleLockStatus deviceSingleLockStatus = new DeviceSingleLockStatus();
        deviceSingleLockStatus.setDeviceNo(deviceGrid.getDeviceNo());
        deviceSingleLockStatus.setDeviceGridId(deviceGrid.getDeviceGridId());
        deviceSingleLockStatus.setSerialNo(deviceGrid.getSerialNo());
        deviceSingleLockStatus.setSerialIndex(deviceGrid.getSerialIndex());
        deviceSingleLockStatus.setMacNo(deviceGrid.getMacNo());
        return deviceSingleLockStatus;
    }

    public static Order getOrder(PushOrder offlineOrderPushSyncD2s) {
        Order order = new Order();
        order.setPhone(offlineOrderPushSyncD2s.getPhone());
        order.setDeviceNo(offlineOrderPushSyncD2s.getDeviceNo());
        order.setDeviceGridId(offlineOrderPushSyncD2s.getDeviceGridId());
        order.setOpenPwd(offlineOrderPushSyncD2s.getOpenPwd());
        order.setOrderNo(offlineOrderPushSyncD2s.getOrderNo());
        if (offlineOrderPushSyncD2s.getStartTime() != null && offlineOrderPushSyncD2s.getStartTime() > 0) {
            order.setStartTime(new Date(offlineOrderPushSyncD2s.getStartTime()));
            //离线订单的创建时间需要和开始时间一致，不然统计不准确
            //order.setCreateTime(order.getStartTime());
        }
        if (offlineOrderPushSyncD2s.getEndTime() != null && offlineOrderPushSyncD2s.getEndTime() > 0) {
            order.setEndTime(new Date(offlineOrderPushSyncD2s.getEndTime()));
        }

        order.setOrderStatus(offlineOrderPushSyncD2s.getOrderStatus());
        order.setIdNo(offlineOrderPushSyncD2s.getIdNo());
        order.setIsOffline(offlineOrderPushSyncD2s.getIsOffline());
        order.setOrderType(offlineOrderPushSyncD2s.getOrderType());
        order.setPayWay(OrderPayWayEnum.system_pay.getCode());
        if (!StringUtils.isEmpty(offlineOrderPushSyncD2s.getPayWay())) {
            order.setPayWay(offlineOrderPushSyncD2s.getPayWay());
        }
        order.setUpdateTime(new Date());
        return order;

    }


    /**
     * 绑定设备信息
     *
     * @param bindReq
     * @return
     */
    public BindResp bindDevice(BindDevice bindReq) {
        BindResp bindResp = new BindResp();
        bindResp.setBingSuccess(true);
        bindResp.setMsg("ok");
        String deviceNo = bindReq.getDeviceNo();
        //设备绑定
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            bindResp.setBingSuccess(false);
            bindResp.setMsg("device empty");
            throw new NotPermissionException("device empty");

        }
        //校验设备绑定密码
        if (StringUtils.isEmpty(device.getDevicePwd()) || !device.getDevicePwd().equals(bindReq.getDevicePwd())) {
            bindResp.setBingSuccess(false);
            bindResp.setMsg("devicePwd error");
            throw new NotPermissionException("devicePwd error");
        }
        //更新绑定信息
        device.setDeviceIccid(bindResp.getDeviceIccid());
        device.setDeviceCardNo(bindResp.getDeviceCardNo());
        device.setChannel(bindReq.getChannel());
        device.setDeviceImei(bindResp.getDeviceImei());
        deviceService.updateById(device);
        setBindResp(bindResp, device);

        return bindResp;
    }

    private void setBindResp(BindResp bindResp, Device device) {
        //目前处理单机配置
        bindResp.setHost(nettyHost);
        bindResp.setPort(nettyPort);
        //设备细腻系
        setDeviceInfo(bindResp, device);
        //设备格子信息
        Long deviceId = device.getDeviceId();
        List<DeviceGrid> deviceGridList = deviceGridService.selectByDeviceId(deviceId);
        if (!CollectionUtils.isEmpty(deviceGridList)) {
            setDeviceGrids(bindResp, deviceGridList);
        } else {
            bindResp.setBingSuccess(false);
            bindResp.setMsg("deviceGridList empty");
        }
        //场地信息
        Long positionId = device.getPositionId();
        Position position = positionService.getById(positionId);
        if (position != null) {
            setPositionInfo(bindResp, position);
        } else {
            bindResp.setBingSuccess(false);
            bindResp.setMsg("position empty");
        }


        //公共信息
        Common common = commonService.getOne(Wrappers.lambdaQuery(Common.class).last("limit 1"));
        if (common != null) {
            setCommonInfo(bindResp, common);
            String free_minutes_value = sysConfigService.selectConfigByKey(SYS_FREE_MINUTES_KEY);

            int free_minutes = 10;
            if (StringUtils.isNotEmpty(free_minutes_value)) {
                free_minutes = Integer.parseInt(free_minutes_value);
            }
            BindResp.PositionDto positionInfo = bindResp.getPositionInfo();
            positionInfo.setFeesText(free_minutes, common.getServicePhone());

        } else {
            bindResp.setBingSuccess(false);
            bindResp.setMsg("common empty");
        }
    }

    /**
     * 上传用户日志
     *
     * @param deviceNo
     * @param logType
     * @param file
     * @return
     */
    public String uploadLog(String deviceNo, String logType, MultipartFile file) {
        String originalfileName = file.getOriginalFilename();
        String suffix = StringUtils.substring(originalfileName, originalfileName.lastIndexOf("."), originalfileName.length());
        OssClient storage = OssFactory.instance();
        UploadResult uploadResult;
        try {
            uploadResult = storage.uploadSuffix(file.getBytes(), suffix, file.getContentType());
        } catch (IOException e) {
            throw new ServiceException(e.getMessage());
        }
        String filename = uploadResult.getFilename();
        String url = uploadResult.getUrl();

        DeviceUploadLog deviceUploadLog = new DeviceUploadLog();
        Device device = deviceService.queryByDeviceNo(deviceNo);
        deviceUploadLog.setFileName(filename);
        deviceUploadLog.setFileUrl(url);
        deviceUploadLog.setDeviceNo(deviceNo);
        deviceUploadLog.setLogType(logType);
        deviceUploadLog.setPositionId(device.getPositionId());
        deviceUploadLogService.save(deviceUploadLog);
        return url;
    }


    /**
     * @param deviceNo
     * @param deviceGridId
     * @param orderNo
     * @param cardNo
     * @return
     */
    public VerifyCardResp verifyCardNo(String deviceNo, Long deviceGridId, String orderNo, String cardNo) {
        VerifyCardResp verifyCardResp = new VerifyCardResp();
        boolean validCard = IdcardUtil.isValidCard(cardNo);
        long count = orderService.count(Wrappers.lambdaQuery(Order.class)
            .eq(Order::getDeviceNo, deviceNo)
            .in(Order::getOrderStatus, OrderStatusEnum.USED_DONE, OrderStatusEnum.IN_USED)
            .eq(Order::getIdNo, cardNo));
        Order order = orderService.getByOrderNo(orderNo);
        if (count > 0 || !validCard || order == null || !order.getDeviceGridId().equals(deviceGridId)) {
            verifyCardResp.setOk(false);
            return verifyCardResp;
        }

        order.setIdNo(cardNo);
        order.setRemark("用户使用身份证号码开锁");
        orderService.updateById(order);

        verifyCardResp.setOk(true);
        verifyCardResp.setMsg(order.getRemark());
        return verifyCardResp;
    }

    private void saveOperateLog(Long deviceId, Long deviceGridId, Order order) {
        DeviceOperateLogBo operateLogBo = new DeviceOperateLogBo();
        if (order!=null){
            operateLogBo.setUserId(order.getUserId());
            operateLogBo.setPositionId(order.getPositionId());
            operateLogBo.setOrderNo(order.getOrderNo());
        }

        operateLogBo.setDeviceId(deviceId);
        operateLogBo.setDeviceGridId(deviceGridId);
        operateLogBo.setStatus("open");
        operateLogBo.setRemark("发送指令中");
        deviceOperateLogService.insertByBo(operateLogBo);
    }

    private void saveOperateSuccessLog(Long deviceId, Long deviceGridId, Order order) {
        DeviceOperateLogBo operateLogBo = new DeviceOperateLogBo();
        if (order!=null){
            operateLogBo.setUserId(order.getUserId());
            operateLogBo.setPositionId(order.getPositionId());
            operateLogBo.setOrderNo(order.getOrderNo());
        }

        operateLogBo.setDeviceId(deviceId);
        operateLogBo.setDeviceGridId(deviceGridId);
        operateLogBo.setStatus("open");
        operateLogBo.setRemark("开锁成功");
        deviceOperateLogService.insertByBo(operateLogBo);
    }


    /*****************************以下是发送设备指令功能************************************/
    /*****************************以下是发送设备指令功能************************************/
    /*****************************以下是发送设备指令功能************************************/


    /**
     * 重启设备指令
     * RESTART_DEVICE("RESTART_DEVICE", CommonCommand.class),
     *
     * @return
     */
    public boolean restartDevice(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.RESTART_DEVICE);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 设置设备基础信息
     * SET_DEVICE_POSITION("SET_DEVICE_POSITION", SetDevicePosition.class),
     *
     * @return
     */
    public boolean setDevicePosition(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        SetDevicePosition setDevicePosition = new SetDevicePosition();
        setBindResp(setDevicePosition, device);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.SET_DEVICE_POSITION);
        builder.data(JSONUtil.parseObj(setDevicePosition));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 全部开锁
     *
     * @return
     */
    public boolean controlOpenAll(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.CONTROL_OPEN_ALL);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }

    /**
     * SYNCHRONOUS_GRID_LIST("SYNCHRONOUS_GRID_LIST", CommonCommand.class),
     *
     * @return 同步全部格子状态
     */
    public boolean synchronousGridList(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.SYNCHRONOUS_GRID_LIST);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 批量设置格子状态,会从数据库中读取
     * BATCH_SET_GRID("BATCH_SET_GRID", BatchSetGrid.class),
     *
     * @return 同步全部格子状态
     */
    public boolean batchSetGrid(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            return false;
        }

        List<DeviceGrid> deviceGrids = deviceGridService.selectByDeviceId(device.getDeviceId());
        List<DeviceSingleLockStatusReply> singleLockStatusReplies = deviceGrids.stream().map(a -> setGridLockReply(a)).collect(Collectors.toList());
        BatchSetGrid setDevicePosition = new BatchSetGrid();
        setDevicePosition.setDeviceNo(deviceNo);
        setDevicePosition.setDeviceGrids(singleLockStatusReplies);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.BATCH_SET_GRID);
        builder.data(JSONUtil.parseObj(setDevicePosition));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);

    }

    /**
     * 设备信息同步
     * DEVICE_COMMON_INFO_SYNC("DEVICE_COMMON_INFO_SYNC", DeviceCommonInfoSync.class),
     *
     * @return 设备信息同步
     */
    public boolean deviceCommonInfoSync(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            return false;
        }
        DeviceCommonInfoSync deviceCommonInfoSync = new DeviceCommonInfoSync();
        deviceCommonInfoSync.setDeviceNo(deviceNo);
        //场地信息
        Long positionId = device.getPositionId();
        String free_minutes_value = sysConfigService.selectConfigByKey(SYS_FREE_MINUTES_KEY);
        int free_minutes = 10;
        if (StringUtils.isNotEmpty(free_minutes_value)) {
            free_minutes = Integer.parseInt(free_minutes_value);
        }


        //公共信息
        Common common = commonService.getOne(Wrappers.lambdaQuery(Common.class).last("limit 1"));
        if (common != null) {
            BindResp.CommonDto commonDto = getCommonDto(common);
            deviceCommonInfoSync.setCommonInfo(commonDto);
        }


        Position position = positionService.getById(positionId);
        if (position != null) {
            BindResp.PositionDto positionDto = getPositionDto(position, device);
            positionDto.setFeesText(free_minutes, common.getServicePhone());
            deviceCommonInfoSync.setPositionId(positionId);
            deviceCommonInfoSync.setPositionInfo(positionDto);
        }

        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.DEVICE_COMMON_INFO_SYNC);
        builder.data(JSONUtil.parseObj(deviceCommonInfoSync));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 控制蓝牙开关
     * CONTROL_BLE_SWITCH("CONTROL_BLE_SWITCH", ControlBleSwitch.class),
     *
     * @return
     */
    public boolean controlBleSwitch(String deviceNo, String blueMac, Boolean open) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        ControlBleSwitch controlBleSwitch = new ControlBleSwitch();
        controlBleSwitch.setDeviceNo(deviceNo);
        controlBleSwitch.setMacAddress(blueMac);
        controlBleSwitch.setOpen(open);
        builder.code(MessageEnum.CONTROL_BLE_SWITCH);
        builder.data(JSONUtil.parseObj(controlBleSwitch));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 更新蓝牙版本
     * UPGRADE_BLE("UPGRADE_BLE", UpgradeBle.class),
     *
     * @return
     */
    public boolean upgradeBle(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        UpgradeBle upgradeBle = new UpgradeBle();
        upgradeBle.setDeviceNo(deviceNo);
        BluetoothVersion bluetoothVersion = bluetoothVersionService.getOne(Wrappers.lambdaQuery(BluetoothVersion.class)
            .eq(BluetoothVersion::getStatus, "open")
            .eq(BluetoothVersion::getDeviceNo, deviceNo)
            .orderByDesc(BluetoothVersion::getVersionCode).last(" limit 1"));
        if (bluetoothVersion != null) {
            SysOssVo sysOss = sysOssService.getById(Long.valueOf(bluetoothVersion.getFileUrl()));
            if (sysOss != null) {
                upgradeBle.setDeviceNo(bluetoothVersion.getDeviceNo());
                upgradeBle.setFileUrl(sysOss.getUrl());
                upgradeBle.setFileMd5(bluetoothVersion.getFileMd5());
                upgradeBle.setVersionCode(bluetoothVersion.getVersionCode());
                upgradeBle.setVersionName(bluetoothVersion.getVersionName());
            }
        }

        builder.code(MessageEnum.UPGRADE_BLE);
        builder.data(JSONUtil.parseObj(upgradeBle));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 推送订单--->还需要推送 开锁
     */
    public boolean pushOrder(String deviceNo, String orderNo) {
        Order order = orderService.getByOrderNo(orderNo);
        if (order == null || !order.getDeviceNo().equals(deviceNo)) {
            return false;
        }
        PushOrder pushOrder = getPushOrder(order);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.PUSH_ORDER);
        builder.data(JSONUtil.parseObj(pushOrder));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }

    /**
     * 推送订单--->还需要推送 开锁,根据订单号推送订单。(很少用)
     */
    public boolean pushByOrderNo(String orderNo) {
        Order order = orderService.getByOrderNo(orderNo);
        String deviceNo = order.getDeviceNo();
        if (order == null) {
            return false;
        }
        PushOrder pushOrder = getPushOrder(order);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.PUSH_ORDER);
        builder.data(JSONUtil.parseObj(pushOrder));
        MessageObject messageObject = builder.build();
        messageService.sendMessage(deviceNo, messageObject);
        return this.controlOpen(pushOrder.getDeviceNo(), pushOrder.getDeviceGridId(), order.getOrderNo());
    }

    /**
     * 回调开锁(根据自定义交易号)
     *
     * @param outTradeNo
     * @return
     */
    public boolean openByOutTradeNo(String outTradeNo) {
        Order order = orderService.getOne(Wrappers.<Order>lambdaQuery().eq(Order::getOutTradeNo, outTradeNo));
        if (order == null) {
            return false;
        }
        return pushByOrderNo(order.getOrderNo());
    }


    /**
     *
     */
    public boolean controlOpen(String deviceNo, Long deviceGridId, String orderNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            return false;
        }

        Order order = orderService.getOne(Wrappers.<Order>lambdaQuery()
            .eq(Order::getDeviceNo, deviceNo)
            .eq(StringUtils.isNotEmpty(orderNo), Order::getOrderNo, orderNo)
            .orderByDesc(Order::getCreateTime)
            .last(" limit 1")
        );

        DeviceGrid deviceGrid = deviceGridService.getById(deviceGridId);
        ControlOpen controlOpen = getControlOpen(deviceGrid, order);

        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.CONTROL_OPEN);
        builder.data(JSONUtil.parseObj(controlOpen));
        MessageObject messageObject = builder.build();
        saveOperateLog(deviceGrid.getDeviceId(), deviceGrid.getDeviceGridId(), order);
        return messageService.sendMessage(deviceNo, messageObject);
    }

    /**
     * ORDER_LIST_SYNC("ORDER_LIST_SYNC", OrderListSync.class),
     */
    public boolean orderListSync(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            return false;
        }
        List<Order> inUsedOrders = orderService.list(Wrappers.lambdaQuery(Order.class)
            .in(Order::getOrderStatus, OrderStatusEnum.IN_USED)
            .eq(Order::getDeviceNo, device.getDeviceNo()));
        List<PushOrder> pushOrders = inUsedOrders.stream().map(a -> getPushOrder(a)).collect(Collectors.toList());
        OrderListSync orderListSync = new OrderListSync();
        orderListSync.setDeviceNo(deviceNo);
        orderListSync.setOrderList(pushOrders);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.ORDER_LIST_SYNC);
        builder.data(JSONUtil.parseObj(orderListSync));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 获取设备SIM卡信息
     *
     * @return
     */
    public boolean getSimInfo(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.GET_SIM_INFO);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 进入设备管理后台
     *
     * @return
     */
    public boolean adminExec(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.ADMIN_EXEC);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 设置管理账号
     *
     * @return
     */
    public boolean modifyAdminAccount(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            return false;
        }
        ModifyAdminAccount modifyAdminAccount = new ModifyAdminAccount();
        modifyAdminAccount.setAdminUserNo(device.getAdminUser());
        modifyAdminAccount.setAdminPwd(device.getAdminPwd());
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.MODIFY_ADMIN_ACCOUNT);
        builder.data(JSONUtil.parseObj(modifyAdminAccount));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 上传设备日志
     *
     * @return
     */
    public boolean uploadDeviceLog(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.UPLOAD_DEVICE_LOG);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 删除设备日志
     *
     * @return
     */
    public boolean deletedDeviceLog(String deviceNo) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        CommonCommand commonCommand = CommonCommand.builder()
            .deviceNo(deviceNo).build();
        builder.code(MessageEnum.DELETED_DEVICE_LOG);
        builder.data(JSONUtil.parseObj(commonCommand));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }

    /**
     * 删除设备日志
     *
     * @return
     */
    public boolean setGrid(String deviceNo, Long deviceGridId) {
        DeviceGrid deviceGrids = deviceGridService.getById(deviceGridId);
        DeviceSingleLockStatusReply deviceSingleLockStatusReply = setGridLockReply(deviceGrids);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.SET_GRID);
        builder.data(JSONUtil.parseObj(deviceSingleLockStatusReply));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 获取单个锁信息
     *
     * @return
     */
    public boolean deviceSingleLockStatus(String deviceNo, Long deviceGridId) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null) {
            return false;
        }
        DeviceGrid deviceGrid = deviceGridService.getById(deviceGridId);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        DeviceSingleLockStatus deviceSingleLockStatus = getDeviceSingleLockStatus(deviceGrid);
        builder.code(MessageEnum.DEVICE_SINGLE_LOCK_STATUS);
        builder.data(JSONUtil.parseObj(deviceSingleLockStatus));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /*************************************以下是处理设备回复*******************************************/
    /*************************************以下是处理设备回复*******************************************/
    /*************************************以下是处理设备回复*******************************************/
    /*************************************以下是处理设备回复*******************************************/


    /**
     * 上锁信息回复服务端亿
     *
     * @param deviceNo
     * @param reply
     * @return
     */
    public boolean deviceSingleLockStatusReply(String deviceNo, DeviceSingleLockStatusReply reply) {
        Long deviceGridId = reply.getDeviceGridId();
        DeviceGrid deviceGrid = deviceGridService.getById(deviceGridId);
        if (deviceGrid.getDeviceGridId().equals(reply.getDeviceGridId()) && !deviceGrid.getStatus().equals(reply.getStatus())) {
            log.info("设备格子状态服务端状态不同步,同步状态--->deviceGridId:{}--->db：{},machine:{}", deviceGrid.getDeviceGridId(), deviceGrid.getStatus(), reply.getStatus());
            deviceGrid.setStatus(reply.getStatus());
        }
        return deviceGridService.updateById(deviceGrid);
    }


    /**
     * 离线订单上报,需要存储数据，只会推送使用中
     *
     * @param reply
     * @return
     */
    public PushOrder offlineOrderPushSyncD2s(PushOrder reply) {
        log.info("offlineOrderPushSyncD2s==> {}", JSONUtil.toJsonStr(reply));
        String orderNo = reply.getOrderNo();
        Order deviceOrder = getOrder(reply);
        Order orderQuery = orderService.getByOrderNo(orderNo);
        if (orderQuery != null) {

            //离线订单，说订单结束,但是系统还没结束的
            if (deviceOrder.getOrderStatus().equals(OrderStatusEnum.USED_DONE.getCode()) && orderQuery.getOrderStatus().equals(OrderStatusEnum.IN_USED.getCode())) {
                log.info("离线订单，说订单结束,但是系统还没结束的==> 设备订单：{},系统DB订单：{}", JSONUtil.toJsonStr(deviceOrder), JSONUtil.toJsonStr(orderQuery));
                BeanUtil.copyProperties(deviceOrder, orderQuery, CopyOptions.create().ignoreNullValue());
                //结束订单，并处理提现业务。
                //状态还原DB,然后去关闭订单
                //关闭订单需要，使用中的状态才处理。这理设备已经更新为使用完成。但是下面的方法是已经判断啦。所以还原状态处理下
                orderQuery.setOrderStatus(OrderStatusEnum.IN_USED.getCode());
                orderService.close(orderQuery, false,false);
            } else if (!orderQuery.getOrderStatus().equals(OrderStatusEnum.USED_DONE.getCode())){//防止订单已经结束，导致订单更新成未结束....
                BeanUtil.copyProperties(deviceOrder, orderQuery, CopyOptions.create().ignoreNullValue());
                orderService.updateById(orderQuery);
            }

        } else {
            String phone = reply.getPhone();
//          离线订单不关联到用户
//            User user = userService.getOne(Wrappers.lambdaQuery(User.class).eq(User::getPhone, phone).last(" limit 1"));
//            if (user != null) {
//                deviceOrder.setUserId(user.getUserId());
//            }

            Device device = deviceService.queryByDeviceNo(reply.getDeviceNo());
            Long positionId = device.getPositionId();
            deviceOrder.setPositionId(positionId);
            deviceOrder.setOrderType("offline");
            //离线订单的创建时间需要和开始时间一致，不然统计不准确
            deviceOrder.setCreateTime(deviceOrder.getStartTime());
            orderService.save(deviceOrder);
        }
        Long deviceGridId = deviceOrder.getDeviceGridId();
        DeviceGrid deviceGrid = deviceGridService.getById(deviceGridId);
        if (reply.getOrderStatus().equals(OrderStatusEnum.IN_USED.getCode())) {
            deviceGrid.setStatus(DeviceGridStatusEnum.locker.getCode());
            if (orderQuery != null && orderQuery.getOrderStatus().equals(OrderStatusEnum.USED_DONE.getCode())) {
                deviceGrid.setStatus(DeviceGridStatusEnum.unlock.getCode());
            }
        } else if (reply.getOrderStatus().equals(OrderStatusEnum.USED_DONE.getCode())) {
            deviceGrid.setStatus(DeviceGridStatusEnum.unlock.getCode());
        }

        deviceGridService.updateById(deviceGrid);
        PushOrder pushOrder = getPushOrder(deviceOrder);
        return pushOrder;
    }


    /**
     * OFFLINE_ORDER_PUSH_SYNC_D2S_REPLY("OFFLINE_ORDER_PUSH_SYNC_D2S_REPLY", PushOrder.class),
     * 离线订单回复
     */
    public boolean offlineOrderPushSyncD2sReply(PushOrder pushOrder) {
        String deviceNo = pushOrder.getDeviceNo();
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.OFFLINE_ORDER_PUSH_SYNC_D2S_REPLY);
        builder.data(JSONUtil.parseObj(pushOrder));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }


    /**
     * 推送订单结束
     */
    public boolean pushOrderFinish(String orderNo, boolean needOpen) {
        log.info("pushOrderFinish===> {}, needOpen {}",orderNo);
        Order order = orderService.getByOrderNo(orderNo);
        PushOrder pushOrder = getPushOrder(order);

        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.PUSH_ORDER_FINISH);
        builder.data(JSONUtil.parseObj(pushOrder));
        MessageObject messageObject = builder.build();
        if (needOpen) {
            this.controlOpen(pushOrder.getDeviceNo(), pushOrder.getDeviceGridId(), orderNo);
        }
        return messageService.sendMessage(pushOrder.getDeviceNo(), messageObject);
    }


    /**
     * @param queryApkLastVersionD2s
     * @return
     */
    public QueryApkLastVersionD2sReply queryApkLastVersionD2s(QueryApkLastVersionD2s queryApkLastVersionD2s) {
        String currentChannel = queryApkLastVersionD2s.getCurrentChannel();
        DeviceVersion deviceVersion = deviceVersionService.getOne(Wrappers.lambdaQuery(DeviceVersion.class)
            .eq(StringUtils.isNotEmpty(currentChannel), DeviceVersion::getFileChannel, currentChannel)
            .eq(DeviceVersion::getStatus, "open")
            .orderByDesc(DeviceVersion::getVersionCode).last(" limit 1"));
        QueryApkLastVersionD2sReply reply = new QueryApkLastVersionD2sReply();
        if (deviceVersion != null) {

            SysOssVo sysOss = sysOssService.getById(Long.valueOf(deviceVersion.getFileUrl()));
            if (sysOss != null) {
                reply.setFileUrl(sysOss.getUrl());
                reply.setLatestVersion(deviceVersion.getVersionCode());
                reply.setFileMd5(deviceVersion.getFileMd5());
                reply.setFileChannel(deviceVersion.getFileChannel());
            }
        }
        return reply;
    }


    /**
     * 推送指令
     */
    public boolean pushVersion(String deviceNo) {
        QueryApkLastVersionD2s reply = new QueryApkLastVersionD2s();
        Device device = deviceService.queryByDeviceNo(deviceNo);
        reply.setCurrentChannel(device.getChannel());
        QueryApkLastVersionD2sReply versionD2sReply = this.queryApkLastVersionD2s(reply);
        //发送指令
        return queryApkLastVersionD2sReply(deviceNo, versionD2sReply);

    }

    /**
     * 获取最新版本返回
     * QUERY_APK_LAST_VERSION_D2S_REPLY("QUERY_APK_LAST_VERSION_D2S_REPLY", QueryApkLastVersionD2sReply.class),
     */
    public boolean queryApkLastVersionD2sReply(String deviceNo, QueryApkLastVersionD2sReply lastVersionD2sReply) {
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.QUERY_APK_LAST_VERSION_D2S_REPLY);
        builder.data(JSONUtil.parseObj(lastVersionD2sReply));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }

    /**
     * 设备格子信息同步
     *
     * @param deviceNo
     * @param reply
     * @return
     */
    public boolean synchronousGridListReply(String deviceNo, SynchronousGridListReply reply) {

        List<BindResp.DeviceGridDto> deviceGrids = reply.getDeviceGrids();
        //设备格子信息
        Device device = deviceService.queryByDeviceNo(deviceNo);
        Long deviceId = device.getDeviceId();
        List<DeviceGrid> dbList = deviceGridService.selectByDeviceId(deviceId);
        List<DeviceGrid> updates = new ArrayList<>();
        for (DeviceGrid deviceGrid : dbList) {
            for (BindResp.DeviceGridDto grid : deviceGrids) {
                if (deviceGrid.getDeviceGridId().equals(grid.getDeviceGridId()) && !deviceGrid.getStatus().equals(grid.getStatus())) {
                    log.info("设备格子状态服务端状态不同步,同步状态--->deviceGridId:{}--->db：{},machine:{}", deviceGrid.getDeviceGridId(), deviceGrid.getStatus(), grid.getStatus());
                    deviceGrid.setStatus(grid.getStatus());
                    updates.add(deviceGrid);
                }
            }
        }
        return deviceGridService.updateBatchById(updates);
    }


    /**
     * 设备卡信息同步
     *
     * @param deviceNo
     * @param reply
     * @return
     */
    public boolean getSimInfoReply(String deviceNo, GetSimInfoReply reply) {
        //设备格子信息
        Device device = deviceService.queryByDeviceNo(deviceNo);
        device.setDeviceImei(reply.getImei());
        device.setDeviceIccid(reply.getIccid());
        device.setDeviceCardNo(reply.getSimNo());
        return deviceService.updateById(device);
    }

    /**
     * 返回 场地ID;
     *
     * @param deviceNo
     * @param devicePwd
     * @return
     */
    public Long loginD2s(String deviceNo, String devicePwd) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device == null || StringUtils.isEmpty(device.getDevicePwd()) || !devicePwd.equals(device.getDevicePwd())) {
            return null;
        }
        device.setStatus(DeviceStatusEnum.online.getCode());
        device.setConnectTime(new Date());
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                deviceService.updateById(device);
            }
        };
        scheduledExecutorService.schedule(task, 30L, TimeUnit.SECONDS);
        return device.getPositionId();
    }
    /**
     * 返回 场地ID;
     *
     * @param deviceNo
     * @return
     */
    public Long setOnline(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        device.setStatus(DeviceStatusEnum.online.getCode());
        deviceService.updateById(device);
        return device.getPositionId();
    }

    public void logout(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        if (device != null) {
            device.setStatus(DeviceStatusEnum.offline.getCode());
            device.setLossTime(new Date());
            deviceService.updateById(device);
        }
    }

    /**
     * OrderListSync.class
     *
     * @param deviceNo
     * @return
     */
    public boolean queryOrderListSyncD2sReply(String deviceNo) {
        Device device = deviceService.queryByDeviceNo(deviceNo);
        List<Order> inUsedOrders = orderService.list(Wrappers.lambdaQuery(Order.class)
            .eq(Order::getDeviceNo, deviceNo)
            .eq(Order::getOrderStatus, OrderStatusEnum.IN_USED.getCode()));
        List<PushOrder> pushOrders = inUsedOrders.stream().map(a -> getPushOrder(a)).collect(Collectors.toList());
        OrderListSync orderListSync = new OrderListSync();
        orderListSync.setDeviceNo(deviceNo);
        orderListSync.setOrderList(pushOrders);
        MessageObject.MessageObjectBuilder builder = MessageObject.builder();
        builder.code(MessageEnum.QUERY_ORDER_LIST_SYNC_D2S_REPLY);
        builder.data(JSONUtil.parseObj(orderListSync));
        MessageObject messageObject = builder.build();
        return messageService.sendMessage(deviceNo, messageObject);
    }

    /**
     * 开锁回复指令
     *
     * @param openResult
     * @return
     */
    @Transactional
    public boolean deviceControlOpenResultD2s(ControlOpenResult openResult) {
        log.info("开锁指令回复:{}", JSONUtil.toJsonStr(openResult));
        if (!StringUtils.isEmpty(openResult.getOrderNo())) {
            DeviceOperateLog operateLog = deviceOperateLogService.getOne(Wrappers.lambdaQuery(DeviceOperateLog.class)
                .eq(DeviceOperateLog::getOrderNo, openResult.getOrderNo())
                .eq(DeviceOperateLog::getDeviceGridId, openResult.getDeviceGridId())
                .orderByDesc(DeviceOperateLog::getCreateTime)
                .last("limit 1"));
            if (operateLog != null) {
                if (openResult.getSuccess()) {
                    operateLog.setRemark("开锁成功");
                } else {
                    operateLog.setRemark("开锁失败");
                }
                deviceOperateLogService.updateById(operateLog);
            } else {
                Device device = deviceService.queryByDeviceNo(openResult.getDeviceNo());
                Order order = orderService.getByOrderNo(openResult.getOrderNo());
                if (order!=null){
                    saveOperateSuccessLog(device.getDeviceId(), openResult.getDeviceGridId(), order);
                }
            }
        }
        return true;
    }

    public static void main(String[] args) {
        System.out.println(new Date().getTime());
    }
}
